<?php 
class Gold_Repay_Model_Order extends TBT_Rewards_Model_Sales_Order
{
	protected $_addresses = null;
	protected $_nitems;

	/**
     * Initialize resource model
     */
    protected function _construct()
    {
        $this->_init('repay/order');
    }
    
	public function isVirtual()
    {
		$isVirtual = true;
        $countItems = 0;
        foreach ($this->getItemsCollection() as $_item) {

            if ($_item->isDeleted() || $_item->getParentItemId()) {
                continue;
            }
            $countItems ++;
            if (!$_item->getProduct()->getIsVirtual()) {
                $isVirtual = false;
            }
        }
        return $countItems == 0 ? false : $isVirtual;
    }
    
 	public function getItemsCollection($filterByTypes = array(), $nonChildrenOnly = false)
    {
        if (is_null($this->_items)) {
            $this->_items = Mage::getResourceModel('repay/order_item_collection')
                ->setOrderFilter($this);

            if ($filterByTypes) {
                $this->_items->filterByTypes($filterByTypes);
            }
            if ($nonChildrenOnly) {
                $this->_items->filterByParent();
            }

            if ($this->getId()) {
                foreach ($this->_items as $item) {
                    $item->setOrder($this);
                }
            }
        }
        return $this->_items;
    }
    
	/**
     * Trigger collect totals after loading, if required
     *
     * @return Gold_Repay_Model_Order
     */
    protected function _afterLoad()
    {
        // collect totals and save me, if required
        if (1 == $this->getData('trigger_recollect')) {
            $this->collectTotals()->save();
        }
        return parent::_afterLoad();
    }

    public function removeItem($itemId)
    {
		$this->getItemById($itemId)->delete();
        return $this;
    }
	
	public function getEditItemsCollection($filterByTypes = array(), $nonChildrenOnly = false)
    {
        if (is_null($this->_nitems)) {
            $this->_nitems = Mage::getResourceModel('sales/order_item_collection')
                ->setOrderFilter($this->getId());
                
            if ($filterByTypes) {
                $this->_nitems->filterByTypes($filterByTypes);
            }
            if ($nonChildrenOnly) {
                $this->_nitems->filterByParent();
            }

            if ($this->getId()) {
                foreach ($this->_nitems as $item) {
                    $item->setOrder($this);
                }
            }
        }
        return $this->_nitems;
    }
    
    public function getEditAllVisibleItems()
    {
        $items = array();
        foreach ($this->getEditItemsCollection() as $item) {
            if (!$item->isDeleted() && !$item->getParentItemId()) {
                $items[] =  $item;
            }
        }
        return $items;
    }


	public function getCustomerTaxClassId()
    {
        /*
        * tax class can vary at any time. so instead of using the value from session, we need to retrieve from db everytime
        * to get the correct tax class
        */
        //if (!$this->getData('customer_group_id') && !$this->getData('customer_tax_class_id')) {
            $classId = Mage::getModel('customer/group')->getTaxClassId($this->getCustomerGroupId());
            $this->setCustomerTaxClassId($classId);
        //}
        return $this->getData('customer_tax_class_id');
    }

    /**
     * Add product to quote
     *
     * return error message if product type instance can't prepare product
     *
     * @param   mixed $product
     * @return  Mage_Sales_Model_Quote_Item || string
     */
    public function addProduct(Mage_Catalog_Model_Product $product, $request=null)
    {

        if ($request === null) {
            $request = 1;
        }
        if (is_numeric($request)) {
            $request = new Varien_Object(array('qty'=>$request));
        }
        if (!($request instanceof Varien_Object)) {
            Mage::throwException(Mage::helper('sales')->__('Invalid request for adding product to quote'));
        }

        $cartCandidates = $product->getTypeInstance(true)
            ->prepareForCart($request, $product);

        /**
         * Error message
         */

        if (is_string($cartCandidates)) {
            return $cartCandidates;
        }

        /**
         * If prepare process return one object
         */
        if (!is_array($cartCandidates)) {
            $cartCandidates = array($cartCandidates);
        }

        $parentItem = null;
        $errors = array();
        foreach ($cartCandidates as $candidate) {
            $item = $this->_addCatalogProduct($candidate, $candidate->getCartQty());

            /**
             * As parent item we should always use the item of first added product
             */
            if (!$parentItem) {
                $parentItem = $item;
            }
            if ($parentItem && $candidate->getParentProductId()) {
                $item->setParentItem($parentItem);
            }

            /**
             * We specify qty after we know about parent (for stock)
             */
            $item->addQty($candidate->getCartQty());

            // collect errors instead of throwing first one
            if ($item->getHasError()) {
                $errors[] = $item->getMessage();
            }
        }
        if (!empty($errors)) {
            Mage::throwException(implode("\n", $errors));
        }
        return $item;
    }
	/**
     * Whether there are recurring items
     *
     * @return bool
     */
    public function hasRecurringItems()
    {
        foreach ($this->getAllVisibleItems() as $item) {
            if ($item->getProduct() && $item->getProduct()->isRecurring()) {
                return true;
            }
        }
        return false;
    }
    
	/**
     * Collect totals
     *
     * @return Gold_Repay_Model_Order
     */
    public function collectTotals()
    {
        /**
         * Protect double totals collection
         */
        if ($this->getTotalsCollectedFlag()) {
            return $this;
        }
        Mage::dispatchEvent(
            $this->_eventPrefix . '_collect_totals_before',
            array(
                $this->_eventObject=>$this
            )
        );

        //$this->setSubtotal(0);
        //$this->setBaseSubtotal(0);

        $this->setSubtotalWithDiscount(0);
        $this->setBaseSubtotalWithDiscount(0);

        $this->setGrandTotal(0);
        $this->setBaseGrandTotal(0);

        $x = 0;
        foreach ($this->getAllAddresses() as $address) {
        	if ($x == 0)
            {
            	$x++;  
            } 
            else 
            {
            	break;
            }  
            $address->setSubtotal(0);
            $address->setBaseSubtotal(0);

            $address->setGrandTotal(0);
            $address->setBaseGrandTotal(0);

            $address->collectTotals();
            $this->_resetOrderPaymentInfo($address);          
            
            $this->setSubtotal((float)$address->getSubtotal());
            
            $this->setBaseSubtotal((float)$address->getBaseSubtotal());

            $this->setSubtotalWithDiscount(
                (float) $this->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount()
            );
            $this->setBaseSubtotalWithDiscount(
                (float) $this->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount()
            );

            $this->setGrandTotal((float) $this->getGrandTotal() + $address->getGrandTotal());

            $this->setBaseGrandTotal((float) $this->getBaseGrandTotal() + $address->getBaseGrandTotal());
        }

        Mage::helper('sales')->checkQuoteAmount($this, $this->getGrandTotal());
        Mage::helper('sales')->checkQuoteAmount($this, $this->getBaseGrandTotal());

        

        $this->setData('trigger_recollect', 0);

        Mage::dispatchEvent(
            $this->_eventPrefix . '_collect_totals_after',
            array($this->_eventObject => $this)
        );

        $this->setTotalsCollectedFlag(true);
        return $this;
    }
     	
    protected function _resetOrderPaymentInfo($address)
    {
    	if ($address->getPaymentAmount())
    	{
    		$this->setPaymentAmount($address->getPaymentAmount());
    		$this->setBasePaymentAmount($address->getBasePaymentAmount());
    		$this->setPaymentDescription($address->getPaymentDescription());
    	}
    	else 
    	{
    		$this->setPaymentAmount(0);
    		$this->setBasePaymentAmount(0);
    		$this->setPaymentDescription('');
    	}
    }
	public function getAllAddresses()
    {
        $addresses = array();
        foreach ($this->getAddressesCol() as $address) {
            if (!$address->isDeleted()) {
                $addresses[] = $address;
            }
        }
        
        return $addresses;
    }
    
    public function getAddressesCol()
    {
    	if (is_null($this->_addresses)) {
            $this->_addresses = Mage::getModel('repay/order_address')->getCollection()
                ->setOrderFilter($this->getId());

            if ($this->getId()) {
                foreach ($this->_addresses as $address) {
                    $address->setOrder($this);
                }
            }
        }
        return $this->_addresses;
    }
    
	/**
     * Retrieve quote billing address
     *
     * @return Mage_Sales_Model_Quote_Address
     */
    public function getBillingAddress()
    {
        return $this->_getAddressByType(Gold_Repay_Model_Order_Address::TYPE_BILLING);
    }

	/**
     * Retrieve quote address by type
     *
     * @param   string $type
     * @return  Mage_Sales_Model_Quote_Address
     */
    protected function _getAddressByType($type)
    {
        foreach ($this->getAddressesCol() as $address) {
            if ($address->getAddressType() == $type && !$address->isDeleted()) {
                return $address;
            }
        }

        $address = Mage::getModel('repay/order_address')->setAddressType($type);
        $this->addAddress($address);
        return $address;
    }
    /**
     * retrieve quote shipping address
     *
     * @return Mage_Sales_Model_Quote_Address
     */
    public function getShippingAddress()
    {
        return $this->_getAddressByType(Gold_Repay_Model_Order_Address::TYPE_SHIPPING);
    }
    
	/**
     * Get order store identifier
     *
     * @return int
     */
    public function getStoreId()
    {
        if (!$this->hasStoreId()) {
            return Mage::app()->getStore()->getId();
        }
        return $this->_getData('store_id');
    }

    /**
     * Get order store model object
     *
     * @return  Mage_Core_Model_Store
     */
    public function getStore()
    {
        return Mage::app()->getStore($this->getStoreId());
    }

    /**
     * Declare order store model
     *
     * @param   Mage_Core_Model_Store $store
     * @return  Mage_Sales_Model_Quote
     */
    public function setStore(Mage_Core_Model_Store $store)
    {
        $this->setStoreId($store->getId());
        return $this;
    }
  
	/**
     * Prepare data before save
     *
     * @return Mage_Sales_Model_Order
     */
    protected function _beforeSave()
    {        
        return $this;
    }
	/**
     * Save related items
     *
     * @return Mage_Sales_Model_Order
     */
    protected function _afterSave()
    {
        parent::_afterSave();

        if (null !== $this->_payments) {
            $this->getPaymentsCollection()->save();
        }
        return $this;
    }
    
	public function addRepayPayment(Gold_Repay_Model_Order_Payment $payment)
    {
        $payment->setOrder($this)
            ->setParentId($this->getId());
        if (!$payment->getId()) {
            $this->getPaymentsCollection()->addItem($payment);
        }
        return $this;
    }
    
	protected function _hasModelChanged()
    {
        return true;
    }
    
	/**
     * Get all order totals (sorted by priority)
     *
     * @return array
     */
    public function getTotals()
    {
    	$shippingAddress = $this->getShippingAddress();
        //$totals = $shippingAddress->getTotals();
        // Going through all quote addresses and merge their totals
        foreach ($this->getAddressesCol() as $address) {
            if ($address->isDeleted() || $address === $shippingAddress) {
                continue;
            }
            foreach ($address->getTotals() as $code => $total) {
                if (isset($totals[$code])) {
                    $totals[$code]->merge($total);
                } else {
                    $totals[$code] = $total;
                }
            }
        }

        $sortedTotals = array();
        foreach ($this->getBillingAddress()->getTotalModels() as $total) {        	
            /* @var $total Mage_Sales_Model_Quote_Address_Total_Abstract */
            if (isset($totals[$total->getCode()])) {
                $sortedTotals[$total->getCode()] = $totals[$total->getCode()];
            }
        }
        return $sortedTotals;
    }
    
    public function getItemsCol($filterByTypes = array(), $nonChildrenOnly = false)
    {
    	//$this->unsetData();
		$this->_items = null;
        if (is_null($this->_items)) {

            $this->_items = Mage::getModel('repay/order_item')
            	->getCollection()
            	->addFieldToFilter('order_id', $this->getId());
                //->setOrderFilter($this->getId());

            if ($filterByTypes) {
                $this->_items->filterByTypes($filterByTypes);
            }
            if ($nonChildrenOnly) {
                $this->_items->filterByParent();
            }

            if ($this->getId()) {
                foreach ($this->_items as $item) {
                    $item->setOrder($this);
                }
            }
        }

        return $this->_items;
    }
	
	public function getOrderItems()
    {
        $items = array();
        foreach ($this->getItemsCol() as $item) {
            if (!$item->isDeleted()) {
                $items[] =  $item;
            }
        }
        return $items;
    }
    
    public function getNewItemById($itemId)
    {
        return $this->getItemsCol()->getNewItemById($itemId);
    }    	

    /**
     * @return Mage_Sales_Model_Quote_Payment
     */
    public function getPayment()
    {
        foreach ($this->getPaymentsCollection() as $payment) {
            if (!$payment->isDeleted()) {
                return $payment;
            }
        }
        return false;
    }
}
?>